package co.fitstart.admin.handler.impl;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.demo2do.core.BusinessException;
import com.demo2do.core.support.Result;

import co.fitstart.admin.handler.FileHandler;
import co.fitstart.admin.handler.support.FileStorage;
import co.fitstart.entity.order.Order;
import co.fitstart.entity.user.User;

/**
 * 
 * @author jiecheng
 *
 */
@Component("fileHandler")
public class FileHandlerImpl implements FileHandler{
    
    private static final Logger logger = LoggerFactory.getLogger(FileHandlerImpl.class);

    @Value("#{config['file.upload.path']}")
    private String uploadPath;
    
    @Value("#{cloud['cloud.prod']}")
    private String cloudPath;
    
    @Value("#{config['courseware.host']}")
    private String coursewareHost;
    
    /**
     * 
     * @param user
     * @return
     */
    private boolean validateUser(User user) {
        
        if(user.getWechat() == null || StringUtils.isEmpty(user.getWechat().getCode())) {
            logger.trace("user wechat code not exit, do not save qrcode into order package");
            return false;
        }
        
        if(user.getUserFit() == null || user.getUserFit().getHeight() == null || user.getUserFit().getWeight() == null || user.getUserFit().getBmiValue() == null) {
            logger.trace("user fit weight height bmi not exit, do not save qrcode into order package");
            return false;
        }
        
        return true;
    }
    
    /**
     * 
     * @param order
     * @param user
     * @return
     */
    private FileStorage generateOrderFileStorage(Order order, User user) {
        
        // delete old qrcode first
        String filename = org.apache.commons.lang3.StringUtils.replace(order.getProduct().getName(), " ", "-");
        
        String filePath = filename + "/" +
                "[" + order.getOrderStatus().getDescription() + "-" + order.getPaymentStatus().getDescription() + "]" + filename + "_" + 
                user.getName() + "_" + user.getWechat().getCode() + "_" + 
                user.getUserFit().getHeight() + "_" + user.getUserFit().getWeight() + "_" + user.getUserFit().getBmiValue();
        
        logger.info("generateOrderFileStorage# generate fileStorage with fileName [{}] and filePath [{}]", filename, filePath);
        FileStorage fileStorage = new FileStorage(filePath, user.getMobile(), "jpg");
        
        return fileStorage;
    }
    
    /* (non-Javadoc)
     * @see co.fitstart.mobile.handler.FileHandler#save(co.fitstart.mobile.entity.FileStorage, java.io.InputStream)
     */
    public void saveQrcode(Order order, User user, InputStream inputStream) {
        
        if(inputStream == null) {
            throw new BusinessException("上传文件为空！");
        }
        
        // validate user could save order qrcode or not
        if(!this.validateUser(user)) {
            throw new BusinessException("用户数据不完整！");
        }
        
        // generate order qrcode fileStorage
        FileStorage fileStorage = this.generateOrderFileStorage(order, user);
        
        // save order qrcode into file
        this.save(fileStorage, inputStream);
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.handler.FileHandler#saveUserQrcode(java.lang.String, java.io.InputStream)
     */
    public Result saveUserQrcode(User user, InputStream inputStream) {
        String code = user.getWechat().getCode();
        
        logger.info("saveUserQrcode() code [{}]", code);
        
        Result result = new Result();

        if(inputStream == null) {
            throw new BusinessException("上传文件为空！");
        }
        
        // validate user could save order qrcode or not
        if(!this.validateUser(user)) {
            throw new BusinessException("用户数据不完整！");
        }
        
        // save inputstream into file with floder and path
        FileStorage fileStorage = new FileStorage("/user/qrcode/" + code, code, "jpg");
        this.save(fileStorage, inputStream);
        
        result.success().data("fileName", fileStorage.getPath() + "/" + fileStorage.getFileName());
        return result;
    }
    
    /*
     * (non-Javadoc)
     * @see co.fitstart.admin.handler.FileHandler#saveVideo(java.lang.String, java.lang.String, java.io.InputStream)
     */
    public String saveVideo(String filename, String orginFileName, InputStream inputStream) throws IOException {
        //1. 根据源文件名获取（文件名，扩展名），
        String extendName = StringUtils.split(orginFileName, ".")[1];
        
        //2. 新建文件 （新建文件名为系统指定文件名，扩展名为源文件扩展名， 路径为指定路径）
        File file = new File(this.coursewareHost, "/" + filename + "." + extendName);
        
        //3. 将字节流copy到新文件
        FileUtils.copyInputStreamToFile(inputStream, file);
        
        //4. 返回文件路径 + 文件名 + 扩展名
        return this.cloudPath + "/" + filename + "." + extendName;
    }
    
    /**
     * 
     * @param fileStorage
     * @param inputStream
     * @return
     */
    protected String save(FileStorage fileStorage, InputStream inputStream) {

        // 1. 新建文件 （新建文件名为系统指定文件名，扩展名为源文件扩展名， 路径为指定路径）
        File file = new File(this.uploadPath + fileStorage.getPath(), fileStorage.getFileName());
        
        // 2. 将字节流copy到新文件
        try {
            FileUtils.copyInputStreamToFile(inputStream, file);
        } catch (IOException e) {
            logger.error("#save() error");
            throw new BusinessException("文件存储失败");
        }
        
        // 3. 返回文件路径 + 文件名 + 扩展名
        return fileStorage.getFileName();
    }

    /*
     * (non-Javadoc)
     * @see com.demo2do.absolute.admin.handler.FileHandle#delete(java.lang.String)
     */ 
    public boolean delete(String filename) {
        File file = FileUtils.getFile(filename);
        return FileUtils.deleteQuietly(file);
    }
    
}
